Skip to content

fix: enforce back-channel logout on subsequent requests by rehydrating session state - #852

Merged
kishore7snehil merged 7 commits into
mainfrom
fix/backchannel-logout-session-rehydration
Sep 2, 2026
Merged

fix: enforce back-channel logout on subsequent requests by rehydrating session state#852
kishore7snehil merged 7 commits into
mainfrom
fix/backchannel-logout-session-rehydration

Conversation

@kishore7snehil

@kishore7snehil kishore7snehil commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Changes

Auth0::getState() rehydrated the user, id token, access token, scope, expiration, and refresh token from session storage, but not the backchannel key. setBackchannel() persists that key to session storage on login, yet getState() never read it back, so on any subsequent request getBackchannel() returned null and the enforcement check in getCredentials() short-circuited. A back-channel logout that had been queued was therefore not applied to later requests, and the session stayed authenticated.

🐛 Bug Fix:

  • Auth0::getState() now rehydrates the backchannel key from session storage alongside the other persisted session values, so a queued back-channel logout is enforced on subsequent requests
  • SdkState registers backchannel in its property defaults and validators, so the rehydrated value is accepted when the state is reconstructed
  • getCredentials() now gates the enforcement block on the backchannel key instead of the id token. The id token is only rehydrated when persistIdToken is enabled, so with that option off the queued logout was skipped. The backchannel key is set only for a real session via exchange(), so it separates a session from a bearer token just as well without depending on that setting

References

N/A

Testing

  • getCredentials() enforces a queued backchannel logout on a subsequent request logs in, asserts a fresh instance sees the live session, queues a back-channel logout, then asserts a fresh instance reports no credentials

  • Added a CookieStore variant covering the default storage backend

  • Added a persistIdToken => false variant, the case where the id token is not rehydrated, which fails against the old id-token gate

  • This change adds unit test coverage

  • This change has been tested on the latest version of the platform/language

Contributor Checklist

…ross requests

getState() reloaded user, id token, access token, scope, expiration, and
refresh token from session storage but not the backchannel key, so on a
subsequent request getBackchannel() was null and the enforcement check in
getCredentials() short-circuited. Rehydrate the key from session storage and
register it in SdkState's property defaults and validators so it is accepted.
@kishore7snehil
kishore7snehil requested a review from a team as a code owner August 6, 2026 16:12
Comment thread src/Auth0.php
Comment thread src/Configuration/SdkState.php
Comment thread tests/Unit/Auth0Test.php Outdated
Comment thread tests/Unit/Auth0Test.php Outdated
@kishore7snehil
kishore7snehil changed the base branch from v9 to main August 12, 2026 13:49
kishore7snehil added a commit that referenced this pull request Aug 31, 2026
…ersions (#862)

### Changes

CI installs its dev tools from open version ranges and there is no
committed `composer.lock`, so it recently pulled in a newer Rector
(2.6.x). That version enables `IfToNullCoalescingAssignRector`, which is
why the Rector job started failing on unrelated PRs.

- The rule rewrites `if (null === $x) { $x = ...; }` guards to `$x ??=
...`, which is equivalent.
- This affected four pre-existing spots: `src/Token.php`,
`src/Token/Parser.php`, `src/Utility/HttpResponsePaginator.php`, and
`src/Utility/HttpTelemetry.php`.
- In `src/Token/Parser.php` the `@codeCoverageIgnore` markers were kept
around the rewritten line, since it remains untestable with the current
JWT encoding test libraries.
- Behavior is unchanged.

### References

Unblocks the Rector CI job on open PRs (#852, #853, #861).

### Testing

- [ ] This change adds unit test coverage
- [x] This change has been tested on the latest version of the
platform/language

### Contributor Checklist

- [x] I have read the [Auth0 general contribution
guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [x] I have read the [Auth0 code of
conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
…id token

getCredentials() gated enforcement on the id token, which is only rehydrated
when persistIdToken is enabled, so a queued revocation was skipped when that
option was off. Gate on the backchannel key instead, which is set only for a
real session via exchange(). Add CookieStore and persistIdToken=false coverage.
@kishore7snehil
kishore7snehil force-pushed the fix/backchannel-logout-session-rehydration branch from d9d925b to 80b57f4 Compare September 2, 2026 12:05
@kishore7snehil
kishore7snehil merged commit e8bc10a into main Sep 2, 2026
21 checks passed
@kishore7snehil
kishore7snehil deleted the fix/backchannel-logout-session-rehydration branch September 2, 2026 13:21
@kishore7snehil kishore7snehil mentioned this pull request Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants